﻿using System;
using NUnit.Framework;

namespace Cpuss.Strategies.Tests
{

    /// <summary>
    /// Tests for SJF with expert rule.
    /// </summary>
    [TestFixture]
    public class ShortestJobFirstExpertTest
    {

        /// <summary>
        /// Check to see that the total execution time for the simulation is correct.
        /// </summary>
        [Test]
        public void TotalExecutionTimeCorrectTest()
        {
            ProcessLoad processLoad = new ProcessLoad()
            {
                new Process(1, 33, 0),
                new Process(2, 12, 0),
                new Process(3, 9, 0),
                new Process(4, 675, 0),
                new Process(5, 12, 0),
                new Process(6, 8, 0),
                new Process(7, 503, 0),
                new Process(8, 21, 0),
                new Process(9, 999, 0),
                new Process(10, 2, 0)
            };
            Runner runner = new Runner(processLoad, new ShortestJobFirstExpert(1, 10));
            int actual = 0;

            runner.Completed += (o, e) => actual = e.TotalTime;
            runner.Run();

            Assert.AreEqual(2274, actual);
        }

        /// <summary>
        /// Check to see that the simulation time is correct.
        /// </summary>
        [Test]
        public void IdleCpuTimeTest()
        {
            ProcessLoad processLoad = new ProcessLoad()
            {
                new Process(1, 12, 1)
            };
            Runner runner = new Runner(processLoad, new ShortestJobFirstExpert(1, 5));
            int actual = 0;

            runner.Completed += (o, e) => actual = e.TotalTime;
            runner.Run();

            Assert.AreEqual(13, actual);
        }

        /// <summary>
        /// Check to see that the string returned is correct.
        /// </summary>
        [Test]
        public void ToStringTest()
        {
            ShortestJobFirstExpert actual = new ShortestJobFirstExpert(1, 20);

            Assert.AreEqual("Shortest Job First Expert (Poll Time = 1, Threshold = 20%)", actual.ToString());
        }

        /// <summary>
        /// Check to see that the threshold is greater than 1%. Not 0 as that would be just SJF.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void ThresholdGreaterThanOneTest()
        {
            ShortestJobFirstExpert actual = new ShortestJobFirstExpert(1, 0);
        }

        /// <summary>
        /// Check to see that the correct exception is raised when the % is greater than 100 for theshold.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void ThresholdGreaterThanOneHunderedTest()
        {
            ShortestJobFirstExpert actual = new ShortestJobFirstExpert(1, 101);
        }

        /// <summary>
        /// Check to see that the correct exception is raised when the poll time is less than one.
        /// </summary>
        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void PollTimeLessThanOneTest()
        {
            ShortestJobFirstExpert actual = new ShortestJobFirstExpert(0, 10);
        }

    }

}
